﻿// ------------------------------------------------------------------------------------
//      Copyright (c) 2013 uhavemyword@gmail.com. All rights reserved.
//      Created by Ben at 1/1/2013 11:32:26 PM
// ------------------------------------------------------------------------------------

namespace CP.NLayer.Client.WpfClient.Main
{
    using System.Windows;
    using CP.NLayer.Client.WpfClient.Common;
    using Microsoft.Practices.Prism.Events;
    using Microsoft.Practices.Prism.Logging;
    using Microsoft.Practices.Prism.Modularity;
    using Microsoft.Practices.Prism.Regions;
    using Microsoft.Practices.Prism.UnityExtensions;
    using Microsoft.Practices.ServiceLocation;
    using Microsoft.Practices.Unity;

    public class Bootstrapper : UnityBootstrapper
    {
        /// <summary>
        /// Creates the shell or main window of the application.
        /// </summary>
        /// <returns>The shell of the application.</returns>
        /// <remarks>
        /// If the returned instance is a <see cref="DependencyObject"/>, the
        /// <see cref="Bootstrapper"/> will attach the default <seealso cref="Microsoft.Practices.Composite.Regions.IRegionManager"/> of
        /// the application in its <see cref="Microsoft.Practices.Composite.Presentation.Regions.RegionManager.RegionManagerProperty"/> attached property
        /// in order to be able to add regions by using the <seealso cref="Microsoft.Practices.Composite.Presentation.Regions.RegionManager.RegionNameProperty"/>
        /// attached property from XAML.
        /// </remarks>
        protected override DependencyObject CreateShell()
        {
            return DependencyInjection.Container.Resolve<Shell>();
        }

        /// <summary>
        /// Initializes the shell.
        /// </summary>
        /// <remarks>
        /// The base implemention ensures the shell is composed in the container.
        /// </remarks>
        protected override void InitializeShell()
        {
            base.InitializeShell();
            App.Current.MainWindow = (Window)this.Shell;
            App.Current.MainWindow.Show();
        }

        /// <summary>
        /// Configures the <see cref="IUnityContainer"/>. May be overwritten in a derived class to add specific
        /// type mappings required by the application.
        /// </summary>
        protected override void ConfigureContainer()
        {
            base.ConfigureContainer();

            // Configure my Container following Registrations in this.Container
            DependencyInjection.Container.RegisterInstance<ILoggerFacade>(this.Container.Resolve<ILoggerFacade>());
            DependencyInjection.Container.RegisterInstance<IModuleCatalog>(this.Container.Resolve<IModuleCatalog>());
            DependencyInjection.Container.RegisterInstance<IServiceLocator>(this.Container.Resolve<IServiceLocator>());
            DependencyInjection.Container.RegisterInstance<IModuleInitializer>(this.Container.Resolve<IModuleInitializer>());
            DependencyInjection.Container.RegisterInstance<IModuleManager>(this.Container.Resolve<IModuleManager>());
            DependencyInjection.Container.RegisterInstance<RegionAdapterMappings>(this.Container.Resolve<RegionAdapterMappings>());
            DependencyInjection.Container.RegisterInstance<IRegionManager>(this.Container.Resolve<IRegionManager>());
            DependencyInjection.Container.RegisterInstance<IEventAggregator>(this.Container.Resolve<IEventAggregator>());
            DependencyInjection.Container.RegisterInstance<IRegionViewRegistry>(this.Container.Resolve<IRegionViewRegistry>());
            DependencyInjection.Container.RegisterInstance<IRegionBehaviorFactory>(this.Container.Resolve<IRegionBehaviorFactory>());
            DependencyInjection.Container.RegisterInstance<IRegionNavigationContentLoader>(this.Container.Resolve<IRegionNavigationContentLoader>());
            DependencyInjection.Container.RegisterType(typeof(IRegionNavigationJournalEntry), typeof(RegionNavigationJournalEntry));
            DependencyInjection.Container.RegisterType(typeof(IRegionNavigationJournal), typeof(RegionNavigationJournal));
            DependencyInjection.Container.RegisterType(typeof(IRegionNavigationService), typeof(RegionNavigationService));
        }

        protected override void InitializeModules()
        {
            base.InitializeModules();
        }

        protected override IModuleCatalog CreateModuleCatalog()
        {
            // Modules are copied to a directory as part of a post-build step.
            // These modules are not referenced in the project and are discovered by inspecting a directory.
            // Module projects have a post-build step to copy themselves into that directory.
            return new DirectoryModuleCatalog() { ModulePath = @".\Modules" };
        }
    }
}
